<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
class Tut_Form_validation extends CI_Form_validation
{
    
    public function alpha_extra($str, $extra)
    {
        return ( ! preg_match("/^([a-z0-9{$extra}])+$/i", $str)) ? FALSE : TRUE;
    }
    
    /**
     * Match one field to another
     *
     * @access    public
     * @param    string
     * @param    field
     * @return    bool
     */
    public function is_unique($str, $field) {
        @list($field, $id)=explode('-', $field);
        @list($table, $field)=explode('.', $field);
        $query = $this->CI->db->limit(1)->get_where($table, array($field => $str));
        if ($query->num_rows() === 0) {
            return true;
        }
        if ($id && ($id == $query->row()->id)) {
            return true;
        }
        return false;
    }
    
    /**
    * tests to see if a required file is uploaded
    * 
    * @param mixed $file
    */
    function file_required($file)
    {
        if($file['size']===0)
        {
            $this->set_message('file_required','Uploading a file for %s is required.');
            return FALSE;
        }
        
        return TRUE;
    }
    
    /**
    * tests to see if a file is within expected file size limit
    * 
    * @param mixed $file
    * @param mixed $max_size
    */
    function file_size_max($file,$max_size)
    {
        $max_size_bit = $this->let_to_bit($max_size);
        if($file['size']>$max_size_bit)
        {
            $this->set_message('file_size_max',"%s is too big. (max allowed is $max_size)");
            return FALSE;
        }
        return true;
    }
    
    /**
    * tests to see if a file is bigger than minimum size
    * 
    * @param mixed $file
    * @param mixed $min_size
    */
    function file_size_min($file,$min_size)
    {
        $max_size_bit = $this->let_to_bit($max_size);
        if($file['size']<$min_size_bit)
        {
            $this->set_message('file_size_min',"%s is too small. (Min allowed is $max_size)");
            return FALSE;
        }
        return true;
    }    
    
    /**
    * tests the file extension for valid file types
    * 
    * @param mixed $file
    * @param mixed $type
    */
    function file_allowed_type($file,$type)
    {
        //is type of format a,b,c,d? -> convert to array
        $exts = explode(',',$type);
                
        //is $type array? run self recursively
        if(count($exts)>1)
        {
            foreach($exts as $v)
            {
                $rc = $this->file_allowed_type($file,$v);
                if($rc===TRUE)
                {
                    return TRUE;
                }
            }
        }
        
        //is type a group type? image, application, word_document, code, zip .... -> load proper array
        $ext_groups = array();
        $ext_groups['image'] = array('jpg','jpeg','gif','png');
        $ext_groups['application'] = array('exe','dll','so','cgi');
        $ext_groups['php_code'] = array('php','php4','php5','inc','phtml');
        $ext_groups['word_document'] = array('rtf','doc','docx');
        $ext_groups['compressed'] = array('zip','gzip','tar','gz');
        
        if(array_key_exists($exts[0],$ext_groups))
        {
            $exts = $ext_groups[$exts[0]];
        }
        
        //get file ext
        $file_ext = strtolower(strrchr($file['name'],'.'));
        $file_ext = substr($file_ext,1);
        
        if(!in_array($file_ext,$exts))
        {
            $this->set_message('file_allowed_type',"%s should be $type.");
            return false;        
        }
        else
        {
            return TRUE;
        }
    }
    
    function file_disallowed_type($file,$type)
    {
        $rc = $this->file_allowed_type($file,$type);
        if(!$rc)
        {
            $this->set_message('file_disallowed_type',"%s cannot be $type.");
        }

        return $rc;
    }
    
    /**
    * given an string in format of ###AA converts to number of bits it is assignin
    * 
    * @param string $sValue
    * @return integer number of bits
    */
    function let_to_bit($sValue)
    {
        // Split value from name
        if(!preg_match('/([0-9]+)([ptgmkb]{1,2}|)/ui',$sValue,$aMatches))
        { // Invalid input
            return FALSE;
        }
        
        if(empty($aMatches[2]))
        { // No name -> Enter default value
            $aMatches[2] = 'KB';
        }
        
        if(strlen($aMatches[2]) == 1)
        { // Shorted name -> full name
        $aMatches[2] .= 'B';
        }
        
        $iBit   = (substr($aMatches[2], -1) == 'B') ? 1024 : 1000;
        // Calculate bits:
        
        switch(strtoupper(substr($aMatches[2],0,1)))
        {
            case 'P':
                $aMatches[1] *= $iBit;
            case 'T':
                $aMatches[1] *= $iBit;
            case 'G':
                $aMatches[1] *= $iBit;
            case 'M':
                $aMatches[1] *= $iBit;
            case 'K':
                $aMatches[1] *= $iBit;
            break;
        }

        // Return the value in bits
        return $aMatches[1];
    }    
    
    /**
    * returns false if image is bigger than the dimensions given
    * 
    * @param mixed $file
    * @param array $dim
    */
    function file_image_maxdim($file,$dim)
    {
        log_message('debug','MY_form_validation:file_image_maxdim ' . $dim);
        $dim = explode(',',$dim);
        
        if(count($dim)!==2)
        {
            //bad size given
            $this->set_message('file_image_maxdim','%s has invalid rule expected similar to 150,300 .');
            return FALSE;
        }
        
        log_message('debug','MY_form_validation:file_image_maxdim ' . $dim[0] . ' ' . $dim[1]);
        
        //get image size
        $d = $this->get_image_dimension($file['tmp_name']);
        
        log_message('debug',$d[0] . ' ' . $d[1]);
        
        if(!$d)
        {
            $this->set_message('file_image_maxdim','%s dimensions was not detected.');
            return FALSE;        
        }
                
        if($d[0] < $dim[0] && $d[1] < $dim[1])
        {
            return TRUE;
        }
    
        $this->set_message('file_image_maxdim','%s image size is too big.');
        return FALSE;
    }
    
    /**
    * returns false is the image is smaller than given dimension
    * 
    * @param mixed $file
    * @param array $dim
    */
    function file_image_mindim($file,$dim)
    {
        $dim = explode(',',$dim);
        
        if(count($dim)!==2)
        {
            //bad size given
            $this->set_message('file_image_mindim','%s has invalid rule expected similar to 150,300 .');
            return FALSE;
        }
        
        //get image size
        $d = $this->get_image_dimension($file['tmp_name']);
        
        if(!$d)
        {
            $this->set_message('file_image_mindim','%s dimensions was not detected.');
            return FALSE;        
        }
        
        log_message('debug',$d[0] . ' ' . $d[1]);
        
        if($d[0] > $dim[0] && $d[1] > $dim[1])
        {
            return TRUE;
        }
    
        $this->set_message('file_image_mindim','%s image size is too big.');
        return FALSE;
    }
    
    /**
    * attempts to determine the image dimension
    * 
    * @param mixed $file_name path to the image file
    * @return array
    */
    function get_image_dimension($file_name)
    {
        log_message('debug',$file_name);
        if (function_exists('getimagesize'))
        {
            $D = @getimagesize($file_name);

            return $D;
        }
        
        return FALSE;
    }
    
     /**
     * Return true if input time matches a time pattern
     *
     * @param string $str
     * @param string $pattern
     * @return boolean
     */
    public function datetime_pattern($str, $pattern)
    {
        if ($pattern == '') {
            $pattern = 'Y-m-d H:i:s';
        }

        return (date($pattern, strtotime($str)) != $str) ? FALSE : TRUE;
    }

    /**
     * Return true if input date matches a date pattern
     *
     * @param string $str
     * @param string $pattern
     * @return boolean
     */
    public function date_pattern($str, $pattern)
    {
        if ($pattern == '') {
            $pattern = 'Y-m-d';
        }

        return (date($pattern, strtotime($str)) != $str) ? FALSE : TRUE;
    }
    
    /**
     * Validate URL
     *
     * @access    public
     * @param    string
     * @return    string
     */
    public function valid_url($url)
    {
        $pattern = "/^(http(?:s)?\:\/\/[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*\.[a-zA-Z]{2,6}(?:\/?|(?:\/[\w\-]+)*)(?:\/?|\/\w+\.[a-zA-Z]{2,4}(?:\?[\w]+\=[\w\-]+)?)?(?:\&[\w]+\=[\w\-]+)*)$/";

        if (!preg_match($pattern, $url))
        {
            return false;
        }

        return true;
    }

    /**
     * Test string end with string
     *
     * @access    public
     * @param    string
     * @return    string
     */
    public function end_with($str, $val)
    {
        if( ! preg_match("/{$val}$/i", $str))
        {
            $this->set_message('end_with',"%s should end with $val.");
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }
}

?>
